package com.pb.wkflow.core.service.impl;

import com.pb.wkflow.core.service.WorkflowDefinitionService;
import org.camunda.bpm.engine.RepositoryService;
import org.camunda.bpm.engine.impl.persistence.entity.DeploymentEntity;
import org.camunda.bpm.engine.repository.Deployment;
import org.camunda.bpm.engine.repository.ProcessDefinition;
import org.camunda.bpm.model.bpmn.BpmnModelInstance;
import org.camunda.bpm.model.bpmn.instance.FlowElement;
import org.camunda.bpm.model.bpmn.instance.MultiInstanceLoopCharacteristics;
import org.camunda.bpm.model.bpmn.instance.UserTask;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.util.List;

/**
 * 流程定义查询服务
 * @author 苗益辉
 * @date 2022/9/23 9:40
 */
@Service
public class WorkflowDefinitionServiceImpl implements WorkflowDefinitionService {

    @Autowired
    RepositoryService repositoryService;

    /**
     * 根据流程键值查询流程定义
     * @param processDefineKey 流程键值
     * @param tenantId 租户
     * @return List<ProcessDefinition>
     */
    @Override
    public List<ProcessDefinition> findListByProcessDefineKey(String processDefineKey, String tenantId) {
        return repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(processDefineKey).tenantIdIn(tenantId)
                .list();
    }

    /**
     * 根据流程键值查询流程定义，最新版本
     * @param processDefineKey 流程键值
     * @param tenantId 租户
     * @return ProcessDefinition
     */
    @Override
    public ProcessDefinition findByProcessDefineKeyAndLastVersion(String processDefineKey, String tenantId) {
        return repositoryService.createProcessDefinitionQuery()
                .processDefinitionKey(processDefineKey).tenantIdIn(tenantId)
                .latestVersion().singleResult();
    }

    /**
     * 根据模型部署流程
     * @param processDefineKey 流程键值
     * @param modelInstance 模型
     * @param tenantId 租户
     * @return Deployment
     */
    @Override
    public Deployment deployByModel(String processDefineKey, BpmnModelInstance modelInstance, String tenantId) {
        return repositoryService.createDeployment()
                .tenantId(tenantId)
                .addModelInstance(processDefineKey + ".bpmn", modelInstance).deploy();
    }

    /**
     * 根据部署id查询部署信息
     * @param deploymentId 部署id
     * @return DeploymentEntity
     */
    @Override
    public DeploymentEntity findByDeploymentId(String deploymentId) {
        return (DeploymentEntity) repositoryService.createDeploymentQuery()
                .deploymentId(deploymentId).singleResult();
    }

    /**
     * 查询租户下所有部署信息
     * @param tenantId 租户id
     * @return List<Deployment>
     */
    @Override
    public List<Deployment> findList(String tenantId) {
        return repositoryService.createDeploymentQuery()
                .tenantIdIn(tenantId).list();
    }

    @Override
    public String getIsMulti(BpmnModelInstance modelInstance, String activityId) {
        FlowElement flowElement = modelInstance.getModelElementById(activityId);
        if (flowElement instanceof UserTask) {
            UserTask userTask = (UserTask) flowElement;
            MultiInstanceLoopCharacteristics loopCharacteristics = (MultiInstanceLoopCharacteristics) userTask.getLoopCharacteristics();
            if (loopCharacteristics != null) {
                return "true";
            } else {
                return "false";
            }
        }
        return "false";
    }

    @Override
    public BpmnModelInstance findModel(String processDefineId) {
        return repositoryService.getBpmnModelInstance(processDefineId);
    }

    /**
     * 根据流程定义id获取流程信息
     * @param processDefineId 流程定义id
     * @return ProcessDefinition
     */
    @Override
    public ProcessDefinition findByProcessDefineId(String processDefineId) {
        return repositoryService.getProcessDefinition(processDefineId);
    }

    @Override
    public void deleteProcessDefine(String procDefineId) {
        repositoryService.deleteProcessDefinition(procDefineId, true);
    }
}
